//////////////////////////////////////////////////////////////////////////////////
//	Copyright 2011 by Yosef Grabivker, ryuho@homenetworksoft.com
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//////////////////////////////////////////////////////////////////////////////////

#ifndef GUILOGIC_H_
#define GUILOGIC_H_

#include "def.h"
#include "taskbaricon.h"
#include <wx/timer.h>
#include <vector>
#include "statecontroller.h"
#include "logsaver.h"
#include "scriptgenerator.h"

class CGUILogic: public wxTimer
{
public:
							CGUILogic(class	CMainWnd& wMain);
	virtual					~CGUILogic();
	
	void					Init();
	void					Refresh();
	void					Refresh(PANELTYPE pl);
	void					SetUpdateSpeed(time_t	tVal);
	time_t					GetUpdateSpeed(time_t	tVal) { return m_tUpdateInterval;}
	void					CleanUp();
	void					Save();
	void					Load();
	void					AddToLog(LOGENTRY entry, time_t tNexAddInterval=0);
	void					SaveLogEntry(const LOGENTRY& entry);
	void					GenerateStatusLog();

	APPLOG&					GetLog()  { return m_log; }
	class CSysLogSrv*		GetSysLogServer() { return m_pSysLogSrv; }
	
	void					AddBind( GUIBIND& bind );
	bool					GetBind( GUIBIND& bind, const IGUIBind* pBIND );
	bool					GetBind( GUIBIND& bind, cCmdCode code );
	void					ProcessCmd();
	void					ProcessSysLogCmd();

	void					SetAutoConnect(bool bAutoConnect=true) { m_bAutoConnect = bAutoConnect; }
	
	
	void					StartLinkToRouter(const CONPARAMS& params);
	void					DestroyLinkToRouter(int nReason=cERNone);
	
	void					SetUpdateIntervl(time_t val){ m_tUpdateInterval=val; 	}
	time_t					GetUpdateIntervl(cCmdCode cCode=cCmdNone);

	static bool				IsNormalLevel(const GUIBIND& bind, unsigned char btCurLevel);
	static bool				IsWarningLevel(const GUIBIND& bind, unsigned char btCurLevel);
	static bool				IsAlarmLevel(const GUIBIND& bind, unsigned char btCurLevel);
	static wxString			PanelToName(PANELTYPE pt);
	static wxString			StratToName(RECOVERYSTRAT strat);

	void					ShowLogDlg();
	void					DoStartUpAction();

	bool					IsLogWndShown()	 { return m_pLogDlg!=NULL;		}
	void					OnLogWndClosed() { m_pLogDlg = NULL;			}
	void					OnSysLogThreadFinished() { m_pSysLogSrv=NULL;	}

	void					EnableCmd( cCmdCode cmd, bool bEnable = true );
	void					SetCMDUpdateDelay( cCmdCode cmd, time_t tVal );

	void					SortLog( int nField );
	static bool				m_bSortAsc;

	void					OnFilterLoaded(cSearchOwnerID cID, FILTERS& filters);
	void					ExecuteMACBlock(bool bLog=true);

	bool					IsConnected();
	void					DoRouterReboot(const wxString& strReason);
	RTSTRING				GetSessionLog()	{ return m_strSessLog;			}
	wxString				GetRouterIP()	{ return m_params.strIP;		}
	void					OnSMTPSendLogFailed(const wxString& str);
	void					OnSMTPSendLogSucceeded();
	wxString				GetCurIP();

	//Port forward
	void					ProcessPortForwarding( const PORTFORWARDLIST& lst );
	void					ToglePFRule( const wxString& strRuleName);
	void					ProcessAutoPortForwarding(bool bAuto);
	PORTFORWARDLIST			GetPortForward()		{ return m_lstPortForward;	 }
	bool					GetAutoPortForward()	{ return m_bAutoPortForward; }
	void					ExecutePortForward();
	void					ReInitSysLogSrv();


	unsigned long			GetConntrackMAX();
	NATTIMEOUTS				GetActualTCPTimeOuts()	{ return m_natTimeOuts; }
	void					SetConntractRecordsCount(size_t stRecords) { m_stateController.SetConntractRecordsCount(stRecords); }
	RTSTRING				GetModemCaps() { return m_strModemCaps; }


	void					SendCMDToRouter(cCmdCode code, const wxString& str, CMDSUBCODE subCode=cCmdSubCodeNone, bool bShowADSLProgres=true);
	wxString				GenerateStatusString(GUIBIND& bind);
	void					PrepareToProgramExit();
	void					UpdateStatusBar();
	void					SendActionToRouter(const wxString& str, CMDSUBCODE subCode=cCmdSubCodeNone);


protected:
	void					Notify();
	void					Tick(bool bForce=false);
	void					PrepareRequest(COMMANDREQUEST& req);
	void					UpdateTaskBarIcon();

	wxString				GenerateUsageToolTip();
	void					DoAction( GUIBIND& bind, unsigned char btCurLevel );
	void					LogAction(const GUIBIND& bind, bool bWarning);
	void					ProcessAction(const GUIBIND& bind, bool bWarning);
	wxString				MakeFlushAction();
	wxString				MakeRebootAction();
	void					RequestMaxFromAll();
	void					SetAllValuesToZero();
	void					ReRequestResourceCounters();
	void					OnSysLogMessage( const SYSLOGMSG& msg );
	void					SaveSyslogMsg( const SYSLOGMSG& msg );
	void					OnTextCMD( CMDCODE code, wxString& str );
	void					OnWANAddress( const RTSTRING& str );
	void					OnRouterVersion( const RTSTRING& str );
	wxString				GeneratePingScript();
	void					OnController(const COMMANDRESPONSE& cmd);
	void					DispatchRouterResponse(const COMMANDRESPONSE& cmd, bool& bHandled);

	void					OnScriptResult( CMDSUBCODE subCmd, const RTSTRING& str );
	void					OnProcList( const RTSTRING& str );
	void					OnWirelessCaps( const RTSTRING& str );
	
	
private:
	void					SetPropData(GUIBIND& bind);
	void					CheckPropChanges(GUIBIND& bind);
	bool					IsCMDSupported(CMDCODE code) const;
	bool					IsSameLevel(const GUIBIND& bind, unsigned char btCurLevel, unsigned char btNewCurLevel);
	void					StartSysLogServer();
	void					StopSysLogServer();
	void					SendLogToSMTP();
	void					ProcessAutoForwarding();
	void					UpdatePortForwardGUI();
	void					FilterPFRule(PORTFORWARDRULE& rule, const TEXTLIST& lstAllow, const TEXTLIST& lstBlock, bool bAllowPolicy, unsigned short wPortLow);
	bool					IsInList(const TEXTLIST& lst, const wxString& strProcName);
	void					RemoveFromList(TEXTLIST& lst, const wxString& strProcName);
	wxString				CalculateRouterID(const wxString& str);
	bool					ValidateRegCode(const wxString& str);
	bool					EraseDeletedPortForwardRules();
	void					PortForwardingMarkInProgress();
	void					PortForwardingFinished();
	void					CheckScheduling();
	void					RequestTCPTimeOuts();
	void					RequestRouterVersion();
	void					DestroyProgress();

	
private:
	class	CLinkToRouter*	m_pLink;
	class	CMainWnd&		m_wMain;
	
	typedef std::vector<GUIBIND> BINDS;
	BINDS					m_binds;

	CONPARAMS				m_params;
	time_t					m_tUpdateInterval;

	CTaskBarIcon*			m_pTheTaskBarIcon;

	APPLOG					m_log;
	unsigned long			m_lMessageCount;
	unsigned long			m_lMessageCountCopy;
	unsigned long			m_lMessageCountEq;
	int						m_nThreadCount;

	class CLogViewer*		m_pLogDlg;
	class CSysLogSrv*		m_pSysLogSrv;

	int						m_nLogSortCol;
	bool					m_bAutoConnect;
	RTSTRING				m_strSessLog;
	class wxSMTP*			m_smtp;
	time_t					m_tLastSMTPSendTime;

	SYSLOGMSGSTORE			m_syslogCopy;
	time_t					m_tLastWANIPCheckTime;
	RTSTRING				m_strWANAddr;

	//Port forwarding
	PORTFORWARDLIST			m_lstPortForward;
	bool					m_bAutoPortForward;

	unsigned short			m_wLastMACExecTime;

	NATTIMEOUTS				m_natTimeOuts;

	RTSTRING				m_strVersion;

	CStateController		m_stateController;

	time_t					m_tLastCmdReceived;

	RTSTRING				m_strModemCaps;

	MACENTRY				m_rebootSched;

	time_t					m_tLastReboot;

	CLogSaver				m_logSaverSysLog;
	CLogSaver				m_logSaverAppLog;

	time_t					m_tLastStatus;

	CScriptGenerator		m_scriptGen;

	class CProgressDlg*		m_pProgress;
};

#endif /*GUILOGIC_H_*/
